package com.yiyihealth.cherriesadmin.core.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yiyihealth.cherriesadmin.model.OrdAppointment;
import com.yiyihealth.cherriesadmin.model.OrdSourceDetail;
import com.yiyihealth.cherriesadmin.model.jkt.JThealth;
import com.yiyihealth.cherriesadmin.model.jkt.JktFunc10009;
import com.yiyihealth.cherriesadmin.model.jkt.JktInParameter;

import com.yiyihealth.cherriesadmin.model.jkt.JktOutParameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * @author chen
 */
@Slf4j
@Component
public class JKTUtil {


    public static JktOutParameter jThealthPost(String FunCode, Map<String, Object> jktFunMap, JThealth jThealth) throws Exception {
        JktInParameter inParameter = new JktInParameter();
        inParameter.setMerchantId(jThealth.getMerchantId());
        inParameter.setLogTraceId(IdUtil.simpleUUID());
        inParameter.setInterfaceMethod(FunCode);
        inParameter.setBizContent(JSONUtil.parseObj(jktFunMap));

        /**
         * 签名字符串
         */
        StringBuilder sign = new StringBuilder();
        sign.append("bizContent=");
        sign.append(inParameter.getBizContent());
        sign.append("&");
        sign.append("interfaceMethod=");
        sign.append(inParameter.getInterfaceMethod());
        sign.append("&");
        sign.append("logTraceId=");
        sign.append(inParameter.getLogTraceId());
        sign.append("&");
        sign.append("merchantId=");
        sign.append(inParameter.getMerchantId());

        /**
         * 签名
         */
        System.out.println(sign.toString());
        inParameter.setSign(RSAUtil.sign(sign.toString(), jThealth.getPrivateKey()));
        log.info(FunCode + "接口入参：" + inParameter);
        log.info("verify-------privateKey-------" + jThealth.getPrivateKey());
//        RSAUtil.verify(sign.toString(), inParameter.getSign(), jThealth.getPublicKey());
        System.out.println(jThealth.getJktServiceAddress());

        /**
         * http请求对象
         */
        HttpRequest httpRequest = HttpRequest.post(jThealth.getJktServiceAddress())
                //商户号 金投健康分配的商户号
                .header("merchantId", inParameter.getMerchantId())
                //请求方法
                .header("interfaceMethod", inParameter.getInterfaceMethod())
                //请求日志ID唯一识别流水ID，推荐使用UUID (最大32位)
                .header("logTraceId", inParameter.getLogTraceId())
                //签名
                .header("sign", inParameter.getSign());

        /**
         * 业务入参JSON
         */
        JSONObject bodyJson = JSONUtil.parseObj(inParameter, false, true);
        log.info(inParameter.getSign());
        bodyJson.remove("merchantId");
        bodyJson.remove("interfaceMethod");
        bodyJson.remove("sign");
        log.info(bodyJson.toStringPretty());

        String result = httpRequest.body(bodyJson.toStringPretty()).execute().body();
        System.out.println(FunCode + "接口出参: " +result);
        JktOutParameter outParameter;
        //判断网关调用是否成功
        Boolean sucess = (Boolean) JSONUtil.parseObj(result).get("success");
        if (sucess) {
            String data = JSONUtil.parseObj(result).get("data").toString();
            if (!JSONUtil.isJson(data)) {
                throw new Exception(FunCode + "接口出参: " + bodyJson.toStringPretty() + ";" + data);
            }
            outParameter = JSONUtil.toBean((JSONObject) JSONUtil.parseObj(result).get("data"), JktOutParameter.class);
            if (outParameter.getSuccess().equals(0)) {
                throw new Exception(FunCode + "接口出参: " + bodyJson.toStringPretty() + ";" + outParameter.getRespCode() + " " + outParameter.getRespDesc());
            }
        } else {
            throw new Exception(FunCode + "接口出参: " + bodyJson.toStringPretty() + ";" + JSONUtil.parseObj(result).get("message"));
        }
        log.info(FunCode + "接口出参：" + result);
        System.out.println(outParameter);
        return outParameter;
    }

    public static List<Map.Entry<String, Object>> sortMap(Map<String, Object> map) {
        List<Map.Entry<String, Object>> infos = new ArrayList<Map.Entry<String, Object>>(map.entrySet());

        // 重写集合的排序方法：按字母顺序
        Collections.sort(infos, new Comparator<Map.Entry<String, Object>>() {
            @Override
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return (o1.getKey().compareTo(o2.getKey()));
            }
        });

        return infos;
    }

    public static void jktFunc10009Sou(JktFunc10009 jktFunc10009, JThealth jThealth, OrdSourceDetail sourceDetail) throws Exception {
        jktFunc10009.setDeptId(sourceDetail.getDepId());
        jktFunc10009.setDeptName(sourceDetail.getDepName());

        jktFunc10009.setDoctorId(sourceDetail.getDoctorId());
        jktFunc10009.setDoctorName(sourceDetail.getDoctorName());

        jktFunc10009.setScheduleId(sourceDetail.getSchedulingId());
        jktFunc10009.setPointId(sourceDetail.getId());
        jktFunc10009.setPointNo(sourceDetail.getSerialNumber());
        jktFunc10009.setScheduleTime(sourceDetail.getTimeState().equals(1) ? "1" : "2");
        jktFunc10009.setRegStatus(sourceDetail.getStatus());
//      jktFunc10009.setOrderId(sourceDetail.getAppId());

        List<JSON> jktFun10009InList = new ArrayList<>();
        sortMap(BeanUtil.beanToMap(jktFunc10009));
        jktFun10009InList.add(JSONUtil.parse(jktFunc10009));
        Map<String, Object> FuncMap = new HashMap<>();
        FuncMap.put("list", jktFun10009InList);
        JKTUtil.jThealthPost("10009", FuncMap, jThealth);
    }

    public static void jktFunc10009App(JktFunc10009 jktFunc10009, JThealth jThealth, OrdAppointment appointment) throws Exception {
        jktFunc10009.setDeptId(appointment.getDepId());
        jktFunc10009.setDeptName(appointment.getDepName());
        jktFunc10009.setDoctorId(appointment.getDoctorId());
        jktFunc10009.setDoctorName(appointment.getDoctorName());

        jktFunc10009.setScheduleId(appointment.getSchedulingId());
        jktFunc10009.setPointId(appointment.getSourceDetailId());
        jktFunc10009.setPointNo(appointment.getSerialNumber());
        jktFunc10009.setScheduleTime(appointment.getTimeState().equals(1) ? "1" : "2");
        if (appointment.getAppStatus().equals(0)) {
            jktFunc10009.setRegStatus("1");
        } else {
            jktFunc10009.setRegStatus("0");
        }
        jktFunc10009.setOrderId(appointment.getAppId());

        List<JSON> jktFun10009InList = new ArrayList<>();
        sortMap(BeanUtil.beanToMap(jktFunc10009));
        jktFun10009InList.add(JSONUtil.parse(jktFunc10009));
        Map<String, Object> FuncMap = new HashMap<>();
        FuncMap.put("list", jktFun10009InList);
        JKTUtil.jThealthPost("10009", FuncMap, jThealth);
    }

    public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
        return (o1.getKey().compareTo(o2.getKey()));
    }
}
